<?php

/**
 * CelebrioMail Settings
 *
 * @copyright  Copyright (c) 2011 Celebrio Software
 * @package    CelebrioMail
 */

namespace ApplicationsModule\MailModule;
use WebtopModule\BasePresenter;
use Nette\Environment;
use Nette\Forms\Form;
use Nette\Application\AppForm;

class SettingsPresenter extends BasePresenter {
    
    /** @var MailManagment */
    private $mailManager;

    /** @var array of MailServer */
    private $activeMailServers = array();
    
    /** @var array of compatible providers */
    private $compatibleMailProviders = array("seznam.cz","gmail.com","hotmail.com","hotmail.cz","hotmail.co.uk");
    
    /** @var account to be edited for settings form */
    private $account_to_edit = 0;
    
    /**
     * Lazy getter for MailManagment
     * @return MailManagment
     */
    private function getMailManager() {
        if ($this->mailManager === NULL) {
            $this->mailManager = new MailManagement();
        }
        return $this->mailManager;
    }

    public function startup() {
	parent::startup();
	header ( "Content-type:text/html; charset=utf-8" ); // TODO: poresit
	if ($this->isAjax()) {
	    if (isset ($_GET["do"])&&($_GET["do"]=="settingsForm-submit"||$_GET["do"]=="settingsFormPart1-submit")) {
		$this->invalidateControl("settingsSnippet");
	    } else {
		$this->invalidateControl("celebriomailappSnippet");
	    }
	}

	if(!Environment::getUser()->isLoggedIn()) {
            throw new \Exception("User is not authenticated");
	    return;
        }

	$this->activeMailServers = $this->getMailManager()->getMailServers(Environment::getUser()->getIdentity()->id);

        if ($this->view == "default") {
            $this->view = "settings"; // if no mail server is set up, you got to do that first
        }

	$this->template->activeLink = "settings";
    }
    
    public function renderSettings() {
	if(isset($this->activeMailServers[0])){
	    $activeMailServersList = array();
	    $i = 0;
	    foreach($this->activeMailServers as $mailServer){
		$activeMailServersList[]=array("id"=>$i,"address"=>$mailServer->getAddress());
		$i++;
	    }
	    $this->template->activeMailServersList = $activeMailServersList;
	}
	if(isset($_GET["edit"])&&isset($this->activeMailServers[(int)$_GET["edit"]])){
	    $this->account_to_edit = (int)$_GET["edit"];
	    $this->template->account_to_edit = $this->account_to_edit;
	    $this->template->accountaddress_to_edit = $this->activeMailServers[(int)$_GET["edit"]]->getAddress();
	    $this->template->settingsForm = $this['settingsForm'];
	}
	if(!isset($this->template->settingsForm)) $this->template->settingsForm = $this['settingsFormPart1'];
    }
    
    public function renderRemove(){
	if(isset($_GET["confirm"])&&isset($this->activeMailServers[(int)$_GET["confirm"]])){
	    $this->template->header = sprintf(_("Are your sure that you want to remove %s from Celebrio?"),
		    $this->activeMailServers[(int)$_GET["confirm"]]->getAddress());
	    $this->template->message = _("By removing the account, it will not be accessible from Celebrio anymore but all the e-mails and information will remain on the e-mail provider's server.");
	    $this->template->account_to_be_removed = (int)$_GET["confirm"];
	}elseif(isset($_GET["remove"])&&isset($this->activeMailServers[(int)$_GET["remove"]])){
	    if($this->getMailManager()->removeMailServer($this->activeMailServers[(int)$_GET["remove"]])){
		$this->template->header = _("The account is removed");
		$this->template->message = _("The account was removed from Celebrio. All the e-mails and information has remained on the e-mail provider's server.");
	    }else{
		$this->template->header = _("The account could not be removed");
		$this->template->message = _("An error occurred, the account could not be removed from Celebrio.");
	    }
	}
    }
    
        protected function createComponentSettingsFormPart1() {
	$form = new AppForm();
	$form->addGroup(_("Add New E-mail Account"));
	$form->addText('mailaddress', _("E-mail address:"))
	     ->addRule(Form::FILLED, _('Please provide your e-mail address.'))
	     ->addRule(Form::EMAIL, _('Please provide a valid e-mail address.'))
	     ->setValue((isset($_GET["edit"])&&isset($this->activeMailServers[$this->account_to_edit])?$this->activeMailServers[$this->account_to_edit]->getAddress():""))
             ->controlPrototype->type("mail");
	$form->addPassword("mailpassword", _("Password:"))
	     ->addRule(Form::FILLED, _('Please provide your password.'));
	$form->addSubmit('submited', _('Submit'));
        $form->onSubmit[] = callback($this, 'settingsSubmittedPart1');
	return $form;
    }

    /**
     * Settings form.
     * @return mixed (form)
     */
    protected function createComponentSettingsForm() {
	$form = new AppForm();
	$form->addGroup(_("Incoming Mail"));
	$form->addText('mailaddress', _("E-mail address:"))
	     ->addRule(Form::FILLED, _('Please provide your e-mail address.'))
	     ->addRule(Form::EMAIL, _('Please provide a valid e-mail address.'))
	     ->setValue((isset($_GET["edit"])&&isset($this->activeMailServers[$this->account_to_edit])?$this->activeMailServers[$this->account_to_edit]->getAddress():""))
	     ->setDisabled((isset($_GET["edit"])?TRUE:FALSE))
             ->controlPrototype->type("mail");
	$form->addText("mailusername", _("User name:"))
	     ->addRule(Form::FILLED, _('Please provide your user name.'))
	     ->setValue((isset($_GET["edit"])&&isset($this->activeMailServers[$this->account_to_edit])?$this->activeMailServers[$this->account_to_edit]->getUsername():""));
	$form->addPassword("mailpassword", _("Password:"))
	     ->addRule(Form::FILLED, _('Please provide your password.'));
	$form->addPassword("mailpassword2", _("Password again:"))
	     ->addRule(Form::FILLED, _('Please provide your password again.'))
	     ->addRule(Form::EQUAL, _('Passwords does not match.'), $form["mailpassword"]);
	$form->addText("inserver", _("Server:"))
	     ->addRule(Form::FILLED, _('Please provide your mail server.'))
	     ->setValue((isset($_GET["edit"])&&isset($this->activeMailServers[$this->account_to_edit])?$this->activeMailServers[$this->account_to_edit]->getInServer():""));
	$form->addSelect("inprotocol", _("Protocol:"), array("pop3"=>"POP3","imap"=>"IMAP"))->setValue((isset($_GET["edit"])&&isset($this->activeMailServers[$this->account_to_edit])?$this->activeMailServers[$this->account_to_edit]->getInProtocol():"pop3"));
	$form->addText("inport", _("Port:"))
	     ->addRule(Form::FILLED, _('Please provide your mail server port.'))
	     ->addRule(Form::NUMERIC, _('Please provide a valid mail server port.'))
	     ->setValue((isset($_GET["edit"])&&isset($this->activeMailServers[$this->account_to_edit])?$this->activeMailServers[$this->account_to_edit]->getInPort():""));
	$form->addCheckbox("inssl",_("Alway use secured connection (SSL)"))->setValue(((isset($_GET["edit"])&&isset($this->activeMailServers[$this->account_to_edit])&&$this->activeMailServers[$this->account_to_edit]->getInSsl()==TRUE)?TRUE:FALSE));
	$form->addGroup(_("Outgoing Mail (SMTP)"));
	$form->addText("outserver", _("Server:"))
	     ->addRule(Form::FILLED, _('Please provide your mail server.'))
	     ->setValue((isset($_GET["edit"])&&isset($this->activeMailServers[$this->account_to_edit])?$this->activeMailServers[$this->account_to_edit]->getOutServer():""));
	$form->addText("outport", _("Port:"))
	     ->addRule(Form::FILLED, _('Please provide your mail server port.'))
	     ->addRule(Form::NUMERIC, _('Please provide a valid mail server port.'))
	     ->setValue((isset($_GET["edit"])&&isset($this->activeMailServers[$this->account_to_edit])?$this->activeMailServers[$this->account_to_edit]->getOutPort():""));
	$form->addCheckbox("outssl",_("Alway use secured connection (SSL)"))->setValue(((isset($_GET["edit"])&&isset($this->activeMailServers[$this->account_to_edit])&&$this->activeMailServers[$this->account_to_edit]->getOutSsl()==TRUE)?TRUE:FALSE));
	$form->addSubmit('submited', _('Submit'));
        $form->onSubmit[] = callback($this, 'settingsSubmitted');
        return $form;
    }
    
    private function saveNewSettingsPart1($values) {
	$provider_name = strtolower(substr($values["mailaddress"], strpos($values["mailaddress"], "@")+1));
	$provider;
	if (in_array($provider_name, $this->compatibleMailProviders)){
	    switch($provider_name){
		case "seznam.cz":
		    $provider = new Providers\EmailSeznamCZ($values["mailaddress"],$values["mailpassword"]);
		    break;
		case "gmail.com":
		    $provider = new Providers\Gmail($values["mailaddress"],$values["mailpassword"]);
		    break;
		case "hotmail.com":
		case "hotmail.cz":
		case "hotmail.co.uk":
		    $provider = new Providers\Hotmail($values["mailaddress"],$values["mailpassword"]);
		    break;
		default:
		    throw new \InvalidStateException("E-mail provider is not implemented.");
	    }
	} else{
	    $this->template->settings_status = sprintf(_("The %s e-mail provider is not supported by default."),$provider_name);
	    $this->template->settingsForm = $this['settingsForm'];
	    return;
	}
	if($provider->checkConnection()){
	    $mailServer = $provider->getMailServer();
	    $mailServer->setUserid(Environment::getUser()->getIdentity()->id);
	    if ($this->getMailManager()->replaceMailServer($mailServer)) {
		$this->template->settings_status = _("E-mail account saved.");
		$this->activeMailServers[] = $mailServer;
	    } else {
		$this->template->settings_status = _("An error occurent while saving mail server settings.");
	    }
	} else {
	    $this->template->settings_status = _("The provided e-mail address and/or password for your e-mail provider do not work.");
	}
	unset($provider);
	unset($mailServer);
    }

    private function saveNewSettings($values) {
	$mailServer = new MailServer(
		Environment::getUser()->getIdentity()->id,
		$values["mailusername"],
		$values["mailpassword"],
		$values["mailaddress"],
		$values["inserver"],
		$values["inprotocol"],
		$values["inport"],
		$values["inssl"],
		$values["outserver"],
		$values["outport"],
		$values["outssl"]);
	
	$mailReceiver = new MailReceiver($mailServer);
	$mailSender = new MailSender($mailServer);
	if ($mailReceiver->connect()) {
	    $folders = $mailReceiver->getMailFolders();
	    $mailServer->setSentFolder($folders["Sent"]);
	    $mailServer->setDraftsFolder($folders["Drafts"]);
	    $mailServer->setTrashfolder($folders["Trash"]);
	    $mailServer->setSpamfolder($folders["Spam"]);
	    if ($mailSender->connect()) {
		if ($this->getMailManager()->replaceMailServer($mailServer)) {
		    $this->template->settings_status = _("Settings saved.");
		    $this->activeMailServers[] = $mailServer;
		} else {
		    $this->template->settings_status = _("An error occurent while saving mail server settings.");
		}
	    } else {
		$this->template->settings_status = _("The provided settings for outgoing mail do not work.");
	    }
	} else {
	    $this->template->settings_status = _("The provided settings for incoming mail do not work.");
	}
	$mailReceiver->close();
    }

    /**
     * process submitted settings
     * @param Form
     */
    public function settingsSubmitted($form) {
	 $values = $form->values;
	 if ($this->isAjax()) $this->invalidateControl("settingsSnippet");
	 $this->saveNewSettings($values);
    }
    
    public function settingsSubmittedPart1($form) {
	$values = $form->values;
	 if ($this->isAjax()) $this->invalidateControl("settingsSnippet");
	 $this->saveNewSettingsPart1($values);
    }

}